home *** CD-ROM | disk | FTP | other *** search
- /*
- * FlatDevice.C - zBuffer device driver.
- *
- * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
- * University of Berne, Switzerland
- * All rights reserved.
- *
- * This software may be freely copied, modified, and redistributed
- * provided that this copyright notice is preserved on all copies.
- *
- * You may not distribute this software, in whole or in part, as part of
- * any commercial product without the express consent of the authors.
- *
- * There is no warranty or other guarantee of fitness of this software
- * for any purpose. It is provided solely "as is".
- *
- */
-
- #include "FlatDevice.h"
- #include "Polygon.h"
- #include "Sphere.h"
-
- static const int defaultConeResolution = 5;
- static const int defaultSphereResolution = 4;
-
- //___________________________________________________________ PolyWithColor
-
- class PolyWithColor {
- friend class FlatDevice;
- public:
- PolyWithColor()
- : p(NULL) {}
- PolyWithColor(Polygon* poly, const Color& color)
- : p(poly), c(color) {}
- ~PolyWithColor() { if (p) delete p; }
-
- private:
- Polygon* p;
- Color c;
- };
-
- typedef PolyWithColor* PolyWithColorPtr;
- declareList(PolyWithColorList, PolyWithColorPtr);
- implementList(PolyWithColorList, PolyWithColorPtr);
-
- //___________________________________________________________ FlatDevice
-
- FlatDevice::FlatDevice(Options* options)
- : DeviceDriver(options), polys(NULL)
- {
- coneResolution = (theOptions->coneResolution <= 0)
- ? defaultConeResolution
- : theOptions->coneResolution;
- sphereResolution = (theOptions->sphereResolution <= 0)
- ? defaultSphereResolution
- : theOptions->sphereResolution;
-
- /*
- * Make up table for cone generation.
- */
- sintable = new real[coneResolution];
- costable = new real[coneResolution];
-
- real alpha;
- for (register int i=0; i<coneResolution; i++) {
- alpha = (2*M_PI*i)/coneResolution;
- SinCos(alpha, sintable[i], costable[i]);
- }
- top = new Vector[coneResolution];
- bottom = new Vector[coneResolution];
-
- /*
- * Generate unit sphere.
- */
- unitSphere = Sphere::tesselation(Vector(0,0,0), 1, sphereResolution);
-
- /*
- * Initialize z-buffer renderer
- */
- zBuffer = new Z_Buffer(new ViewTransform(theOptions->eye,
- theOptions->lookat,
- theOptions->up, theOptions->fov,
- theOptions->resX, theOptions->resY),
- "Image rendered with graphtal",
- theOptions->oname);
- }
-
- FlatDevice::~FlatDevice()
- {
- delete [] sintable;
- delete [] costable;
- delete [] top;
- delete [] bottom;
-
- for (register long i=0; i<unitSphere->count(); i++)
- delete unitSphere->item(i);
- delete unitSphere;
-
- delete zBuffer;
-
- StringTable_Iterator macroItr(macroNames);
- while(macroItr.more()){
- PolyWithColorList* polyList = (PolyWithColorList*) macroItr.cur_value();
- for (i = 0; i<polyList->count(); i++)
- delete polyList->item(i);
- delete polyList;
- macroItr.next();
- }
- }
-
- void FlatDevice::begin(){}
-
- void FlatDevice::end(const BoundingBox&)
- {
- if (theOptions->verbose)
- cerr << "primitives: "<< zBuffer->primitives() << '\n';
-
- zBuffer->writePixmap();
- }
-
- void FlatDevice::cylinder(const Vector& p1, const Vector& p2, real r)
- {
- cone(p1, r, p2, r);
- }
-
- void FlatDevice::cone(const Vector& p1, real r1, const Vector& p2, real r2)
- {
- Vector axis = p2 - p1;
-
- /*
- * Degenerated cone?
- */
- if (axis.normalize() == 0)
- return;
-
- Vector u, v;
-
- /*
- * Find 2 vectors normal to cone axis and to each other.
- */
- u[0] = -axis[1]; u[1] = axis[0]; u[2] = 0;
- if (u.normalize() == 0) {
- u[0] = axis[2]; u[1] = 0; u[2] = -axis[0];
- u.normalize();
- }
- v = axis*u;
-
- Vector d;
- for (register int i=0; i<coneResolution; i++) {
- d = costable[i]*u + sintable[i]*v;
- *(bottom+i) = p1 + d*r1;
- *(top+i) = p2 + d*r2;
- }
-
- for (i=0; i<coneResolution; i++) {
- if (definingMacro) {
- Polygon* p = new Polygon(*(bottom+i), *(top+i),
- *(top+((i+1)%coneResolution)),
- *(bottom+((i+1)%coneResolution)));
- PolyWithColor* pwc = new PolyWithColor(p, currentColor);
- polys->append(pwc);
- }
- else
- zBuffer->renderRectangle(currentColor,
- *(bottom+i), *(top+i),
- *(top+((i+1)%coneResolution)),
- *(bottom+((i+1)%coneResolution)));
- }
- }
-
- void FlatDevice::polygon(Polygon* p)
- {
- if (definingMacro) {
- PolyWithColor* pwc = new PolyWithColor(p, currentColor);
- polys->append(pwc);
- }
- else
- zBuffer->renderPolygon(currentColor, p);
- }
-
- void FlatDevice::sphere(const Vector& pos, real r)
- {
- /*
- * Transform the unit sphere to radius r and position pos.
- */
- for (register long i=0; i<unitSphere->count(); i++) {
- Polygon* p = unitSphere->item(i);
- Polygon* transformedPoly = new Polygon(p->numVertices());
- for (register long j=0; j<p->numVertices(); j++)
- transformedPoly->addVertex(p->vertex(j)*r+pos);
-
- if (definingMacro) {
- PolyWithColor* pwc = new PolyWithColor(transformedPoly, currentColor);
- polys->append(pwc);
- }
- else
- zBuffer->renderPolygon(currentColor, transformedPoly);
- }
- }
-
- void FlatDevice::color(const Color& color)
- {
- currentColor = color;
- }
-
- void FlatDevice::beginMacro(const rcString& macroName)
- {
- definingMacro = 1;
- currentMacroName = macroName;
- polys = new PolyWithColorList(100);
- }
-
- void FlatDevice::endMacro()
- {
- definingMacro = 0;
- macroNames.find_and_replace(currentMacroName, polys);
- polys = NULL;
- }
-
- void FlatDevice::executeMacro(const rcString& macroName,
- const TransMatrix& tmat)
- {
- anyPtr argument;
- if (!macroNames.lookup(macroName, argument))
- Error(ERR_PANIC, "FlatDevice::executeMacro: macro "
- + macroName + " does not exist");
-
- PolyWithColorList* polyList = (PolyWithColorList*) argument;
- for (register long i=0; i<polyList->count(); i++) {
- Polygon* p = new Polygon(*polyList->item(i)->p);
- p->transform(tmat);
-
- if (definingMacro) {
- PolyWithColor* pwc = new PolyWithColor(p, polyList->item(i)->c);
- polys->append(pwc);
- }
- else
- zBuffer->renderPolygon(polyList->item(i)->c, p);
- }
- }
-
-